package ie.dcu.spca.data.db;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.widget.Toast;
import ie.dcu.spca.R;
import ie.dcu.spca.data.BillDataManager;
import ie.dcu.spca.data.CategoryDataManager;
import ie.dcu.spca.data.DataManager;
import ie.dcu.spca.data.ItemDataManager;
import ie.dcu.spca.data.ItemUserDataManager;
import ie.dcu.spca.data.PriceUnitDataManager;
import ie.dcu.spca.data.ProductDataManager;
import ie.dcu.spca.data.UserDataManager;
import ie.dcu.spca.data.memory.MemoryPriceUnitDataManager;
import ie.dcu.spca.model.DBconnection;
import ie.dcu.spca.util.DataSendUtils;

public class DBDataManager implements DataManager {

    private UserDataManager userDataManager = null;
    private CategoryDataManager categoryDataManager = null;
    private ProductDataManager productDataManager = null;
    private PriceUnitDataManager priceUnitDataMangager = null;
    private BillDataManager billDataManager = null;
    private ItemDataManager itemDataManager = null;
    private ItemUserDataManager iuDataManager = null;
    private String dbLocation;
    private Activity parent;

    public DBDataManager(Activity parent) {
        this.parent = parent;

        userDataManager = new DBUserDataManager();
        categoryDataManager = new DBCategoryDataManager();
        productDataManager = new DBProductDataManager();
        priceUnitDataMangager = new MemoryPriceUnitDataManager();
        billDataManager = new DBBillDataManager();
        itemDataManager = new DBItemDataManager();
        iuDataManager = new DBItemUserDataManager();

        (this.productDataManager).loadDefault(priceUnitDataMangager,
                categoryDataManager);
        (this.itemDataManager).loadDefault(productDataManager, userDataManager,
                priceUnitDataMangager, iuDataManager);
        File file = parent.getExternalFilesDir(null);
        dbLocation = file.getAbsolutePath() + File.separator
                + parent.getString(R.string.default_dbname);
        // Log.d("DB Location", dbLocation);
        initDb(parent);
    }

    private void initDb(Activity parent) {

        File file = new File(this.dbLocation);
        if (!file.exists())
            try {
                file.createNewFile();
                InputStream is = null;
                OutputStream os = null;
                is = parent.getAssets().open(
                        parent.getString(R.string.default_dbname));
                os = new FileOutputStream(this.dbLocation);
                byte[] buffer = new byte[1024];
                while (is.read(buffer) != -1)
                    os.write(buffer);
                os.flush();
                is.close();
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }

    public void open() {
        DBconnection.makeInstance(parent, dbLocation);
    }

    @Override
    public BillDataManager billDataManager() {
        return billDataManager;
    }

    @Override
    public CategoryDataManager categoryDataManager() {
        return categoryDataManager;
    }

    @Override
    public ItemDataManager itemDataManager() {
        return itemDataManager;
    }

    @Override
    public ItemUserDataManager itemUserDataManager() {
        return iuDataManager;
    }

    @Override
    public PriceUnitDataManager priceUnitDataManager() {
        return priceUnitDataMangager;
    }

    @Override
    public ProductDataManager productDataManager() {
        return productDataManager;
    }

    @Override
    public UserDataManager userDataManager() {
        return userDataManager;
    }

    @Override
    public void close() {
        DBconnection.getInstance().closedb();
    }

    @Override
    public String getDatabaseUri() {
        return dbLocation;
    }

    @Override
    public void sendDB() {
        close();
        if (this.parent.getString(R.string.default_db_send_method)
                .toLowerCase().startsWith("http")) {

            Toast.makeText(this.parent,
                    this.parent.getString(R.string.default_db_http_sending),
                    Toast.LENGTH_SHORT).show();

            int messageId = R.string.default_db_receiver_http_request_successful;
            if (!throughHttp()) {
                messageId = R.string.default_db_receiver_http_request_failed;
            }
            Toast.makeText(this.parent, this.parent.getString(messageId),
                    Toast.LENGTH_SHORT).show();
        } else {
            throughEmail();
        }
        open();
    }

    private boolean throughHttp() {
        // return DataSendUtils.httpPost(getDatabaseUri(),
        // this.parent.getString(R.string.default_db_receiver_http_url),
        // this.parent.getString(R.string.default_db_receiver_http_form_name));
        return DataSendUtils
                .httpPostBase64(
                        getDatabaseUri(),
                        this.parent
                                .getString(R.string.default_db_receiver_google_url),
                        this.parent
                                .getString(R.string.default_db_receiver_google_form_key),
                        this.parent
                                .getString(R.string.default_db_receiver_google_form_input_name));
    }

    private void throughEmail() {

        Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);

        emailIntent.setType(this.parent.getString(R.string.default_email_mime));

        emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
                new String[] { this.parent
                        .getString(R.string.default_db_receiver_email) });

        String title = this.parent.getString(R.string.default_email_pre_title)
                + (new java.util.Date()).toLocaleString();
        emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, title);

        emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, title);

        emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"
                + getDatabaseUri()));

        this.parent.startActivity(Intent.createChooser(emailIntent, this.parent
                .getString(R.string.default_email_sending)));

    }

}
